import {computed, reactive, ref} from 'vue';
import {
  ElMessage,
  UploadFile,
  UploadFiles,
  UploadProgressEvent,
  UploadProps,
  UploadRawFile,
  UploadUserFile
} from 'element-plus';
import dayjs from 'dayjs';
import {getImageSizeFix} from '@/utils';
import {useAppStore} from '@/store';

export type UploadSuccessCallback = (url: string, file?: UploadFile) => void;
export type AppInfoParserCallback = (result: any, extension: string) => void;

export type UploadItemData = {
  id?: number
  content: string
  type?: number
  orderNum: number
};

export type UploadOptions = {
  limit: number; // 数量限制
  fileSize: number; // 大小限制(MB)
  fileTypes: string[]; // 文件类型
  uploadPath: string; // 图标保存到OSS的路径前缀
  rename: boolean; // 是否重命名图片名称
  serverUpload: boolean; // 是否服务端上传
}

export default function useUpload(itemData: UploadItemData[], callback: UploadSuccessCallback,) {
  // OSS上传需要的数据
  const uploadData = reactive({
    ossType: -1,
    prefixUrl: '',
    actionUrl: '',
    requestData: {},
    fileSuffixMap: {}
  });

  // 上传进度
  const percentage = ref(0);
  const percentageShow = ref(false);
  const percentageColors = [
    {color: '#f56c6c', percentage: 20},
    {color: '#e6a23c', percentage: 40},
    {color: '#5cb87a', percentage: 60},
    {color: '#1989fa', percentage: 80},
    {color: '#6f7ad3', percentage: 100},
  ];

  // 上传参数信息
  const uploadOptions = reactive<UploadOptions>({
    limit: 1, // 数量限制
    fileSize: 5, // 大小限制(MB)
    fileTypes: [], // 文件类型
    uploadPath: 'uploads', // 图标保存到OSS的路径前缀
    rename: true, // 是否重命名图片名称
    serverUpload: true, // 是否服务端上传
  });

  // 可接受的文件类型
  const acceptTypes = computed(() => {
    let accepts = uploadOptions.fileTypes || []
    let types: string[] = []
    for (let item of accepts) {
      types.push(item.split('/')[1])
    }
    return types.join(' / ');
  });

  const appStore = useAppStore();

  // 文件上传前校检
  const beforeFileUpload = async (file: UploadRawFile, callback: AppInfoParserCallback) => {
    // 文件大小校检
    if (file.size / 1024 / 1024 > uploadOptions.fileSize) {
      warningTip(`文件大小不能超过 ${uploadOptions.fileSize} MB!`)
      return false
    }

    // 获取文件扩展
    let extension = file.name.toLowerCase().split('.').splice(-1)[0]
    let fileType = '.' + extension
    // 格式校检
    if (uploadOptions.fileTypes.length > 0 && !uploadOptions.fileTypes.includes(fileType)) {
      warningTip(`文件格式只能是 ${uploadOptions.fileTypes.join(' / ')} !`)
      return false
    }

    // 只有是 ipa 和 apk 的包名才进行解析
    if (extension == 'ipa' || extension == 'apk') {
      // @ts-ignore
      const parser = new window.AppInfoParser(file)
      parser.parse().then(result => {
        console.log('parser info => ', result)
        callback?.(result, extension)
      }).catch(err => {
        console.log('parser app info err => ', err)
      })
    }

    // 然后是服务端上传 直接返回 true
    if (uploadOptions.serverUpload) {
      return true
    }

    // 获取文件名称
    let fileName = file.name
    // 如果需要重命名
    if (uploadOptions.rename) {
      fileName = `${file.uid}.${extension}`
    }

    // 处理OSS上传数据和其他信息
    return handleOssUploadData(file, fileName, uploadOptions);
  };

  // 图片上传校检
  const beforeImageUpload: UploadProps['beforeUpload'] = async (file: UploadRawFile) => {
    // 数量限制
    if (itemData.length >= uploadOptions.limit) {
      warningTip(`当前最多只能上传 ${uploadOptions.limit} 张图片，请移除后上传！`)
      return false
    }

    // 文件大小校检
    if (file.size / 1024 / 1024 > uploadOptions.fileSize) {
      warningTip(`图片大小不能超过 ${uploadOptions.fileSize} MB!`)
      return false
    }

    // 格式校检
    if (uploadOptions.fileTypes.length > 0 && !uploadOptions.fileTypes.includes(file.type)) {
      warningTip(`图片只能是 ${acceptTypes.value} 格式!`)
      return false
    }

    // 如果是服务端上传
    if (uploadOptions.serverUpload) {
      // 直接返回 不进行后续处理
      return true
    }

    // 获取文件名称
    let fileName = file.name
    // 如果需要重命名
    if (uploadOptions.rename) {
      let sizeFix = await getImageSizeFix(file) || ''
      let prefix = file.uid + '' + sizeFix
      let suffix = file.name.toLowerCase().split('.').splice(-1)
      fileName = `${prefix}.${suffix}`
    }

    // 处理OSS上传数据和其他信息
    return handleOssUploadData(file, fileName, uploadOptions);
  }

  // 处理OSS上传数据和其他信息
  const handleOssUploadData = async (file: UploadRawFile, fileName: string, options: UploadOptions) => {
    // 当前时间
    let currDate = dayjs().format('YYYYMMDD')
    console.log(555, 999)
    // 处理前端上传令牌
    return appStore.getOssToken(fileName).then((data: any) => {
      let ossType = data.ossType || -1
      // if (ossType === 1) {
      //   // OSS类型
      //   uploadData.ossType = ossType
      //   // 前缀地址
      //   uploadData.prefixUrl = data.domain + (data.domain.endsWith('/') ? '' : '/')
      //   // 上传地址
      //   uploadData.actionUrl = data.upHost
      //   // 七牛云上传
      //   uploadData.requestData = {
      //     token: data.token,
      //     key: encodeURI(`${options.uploadPath ? options.uploadPath : 'uploads'}/${currDate}/${fileName}`)
      //   }
      //   return true;
      // } else if (ossType === 2) {
      // OSS类型
      uploadData.ossType = 2
      let accessUrl = data.path + '/' + fileName
      uploadData.fileSuffixMap[file.uid] = accessUrl
      // 前缀地址
      uploadData.prefixUrl = data.host + (data.host.endsWith('/') ? '' : '/')
      // 上传地址
      uploadData.actionUrl = data.host
      // 阿里云上传
      uploadData.requestData = {
        OSSAccessKeyId: data.accessid,
        policy: data.policy,
        Signature: data.signature,
        keys: data.path,
        key: accessUrl,
        success_action_status: 200,
      }
      return true;
      // }
      // errorTip('当前设置的OSS上传方式未实现！');
      // return false;
    })
  }

  // 上传成功
  const handleUploadSuccess: UploadProps['onSuccess'] = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {
    if (itemData.length >= uploadOptions.limit) {
      return;
    }
    let tempUrl = ''

    if (uploadData.ossType === 1) {
      tempUrl = uploadData.prefixUrl + response.key
    } else if (uploadData.ossType === 2) {
      tempUrl = uploadData.prefixUrl + uploadData.fileSuffixMap[uploadFile.uid]
    } else {
      let code = response.code || -1
      if (code !== 0 && code != 200) {
        errorTip(response.message || response.msg || '上传失败，请您重新上传！')
        return
      }
      tempUrl = response.data.url
    }

    // 上传成功回调 返回1个Url
    callback?.(tempUrl, uploadFile);

    // 设置上传进度为100%
    percentage.value = 100;
    percentageShow.value = false;
  };

  // 文件数超出数量
  const handleUploadExceed: UploadProps['onExceed'] = (files: File[], uploadFiles: UploadUserFile[]) => {
    percentage.value = 0;
    percentageShow.value = false;
    warningTip(`当前最多只能上传 ${uploadOptions.limit}，请移除后上传！`);
  };

  // 上传异常
  const handleUploadError: UploadProps['onError'] = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {
    percentage.value = 0;
    percentageShow.value = false;
    errorTip('上传失败，请您重新上传！');
  };

  // 上传进度
  const handleUploadProgress: UploadProps['onProgress'] = (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles): void => {
    percentage.value = uploadFile.percentage || 0;
    percentageShow.value = true;
  };

  // 提示信息
  const warningTip = (message: string) => {
    ElMessage.warning({message: message,});
  };

  const errorTip = (message: string) => {
    ElMessage.error({message: message,});
  };

  const successTip = (message: string) => {
    ElMessage.success({message: message,});
  };

  // 对外数据和方法
  return {
    uploadData, uploadOptions, percentage, percentageShow, percentageColors,
    beforeFileUpload,
    beforeImageUpload,
    handleUploadSuccess,
    handleUploadExceed,
    handleUploadError,
    handleUploadProgress
  };
}
